home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mintman / signal.doc < prev   
Text File  |  1991-10-09  |  19KB  |  411 lines

  1. An Introduction to Signals Under MiNT
  2.  
  3. MiNT introduces the new (to TOS) concept of a signal. If you're
  4. familiar with Unix/Posix signals, then MiNT signals will will be
  5. easy to learn; but note that there are some (not so subtle) differences
  6. between MiNT and Unix!
  7.  
  8. What is a Signal?
  9.  
  10. A signal is a small non-negative integer that represents an exceptional event;
  11. something that is very urgent. It's somewhat like an interrupt or
  12. exception to the CPU, only it's implemented in the operating system
  13. instead of in the hardware. Like many exceptions (bus errors, etc.) signals
  14. are usually fatal. Most signals can be caught by programs (so that a
  15. program-defined routine is called) or ignored; if a signal is caught or
  16. ignored, it is no longer fatal. Signals can also be blocked; a
  17. blocked signal is not acted upon until it is unblocked.
  18.  
  19. A signal is said to be sent to a process when the exceptional
  20. condition related to that signal occurs, or when another process sends
  21. the signal with the Pkill system call. The signal is said to
  22. be delivered to the process when that process wakes up and
  23. begins to take whatever actions are appropriate for the signal. Note
  24. that there may be a considerable time interval between the sending of
  25. a signal and its delivery. For example, if process A has blocked the
  26. SIGHUP signal (signal 1), then no SIGHUP will be delivered to it until
  27. it has unblocked that signal, even if process B sends it SIGHUP with
  28. the Pkill system call. Note also that a signal is not
  29. necessarily delivered the same number of times that it is sent. If both
  30. process B and process C send SIGHUP to process A, when process A
  31. unblocks SIGHUP only one SIGHUP will be delivered. This is because signals
  32. are like flags; once a flag has been set (the signal is sent) setting
  33. the flag again will have no effect until it has been cleared (the signal
  34. is delivered).
  35.  
  36. What Signals Are There?
  37.  
  38. There are 32 possible signals, 0-31. Not all of these have been assigned
  39. a meaning under MiNT. Here are the ones that have been given a meaning;
  40. we give the symbolic name for the signal, the corresponding integer,
  41. and the "traditional" meaning for the process that the signal is sent to.
  42. Any signal not listed here should be considered as "reserved" and should not
  43. be used by applications.
  44.  
  45. Unless otherwise noted, the default action for signals is to terminate
  46. the process.
  47.  
  48. #define    SIGNULL        0    [no default action, signal is never delivered]
  49. This isn't really a signal at all; it is never delivered to processes
  50. and has no effect. It exists only so that processes can test to see if
  51. a particular child process has exited, by attempting to send SIGNULL
  52. to the child. If the child exists, the attempt will succeed but nothing
  53. will be done. If the child has terminated, the caller will get an error.
  54. It is not possible to catch or block this signal, since it is never
  55. sent to processes anyway.
  56.  
  57. #define SIGHUP        1
  58. "The terminal that you're connected to is no longer valid." This signal
  59. is commonly sent by, for example, window managers when the user has
  60. closed the window. Processes should not attempt any I/O to their
  61. controlling terminal after receiving this signal, and indeed should probably
  62. exit unless the user has specifically asked them to continue.
  63.  
  64. #define SIGINT        2
  65. "Please stop what you're doing." This signal is sent when the user
  66. presses control-C. It usually means that the process should exit; interactive
  67. processes may wish to catch SIGINT so that the user can use it to
  68. break out of time-consuming tasks.
  69.  
  70. #define SIGQUIT        3
  71. "Stop what you're doing, something's gone wrong!" This signal is sent when
  72. the user presses control-\. It usually indicates a desire to immediately
  73. abort the process because of an error that the user has noticed. It is
  74. generally thought to be "stronger" than SIGINT, and exiting (perhaps after
  75. cleaning up data structures) is an appropriate response to this.
  76.  
  77. #define SIGILL        4
  78. "An illegal instruction has been encountered." This corresponds to the
  79. 680x0 illegal instruction trap, and usually indicates a very serious error;
  80. catching this signal is generally unwise.
  81.  
  82. #define SIGTRAP        5
  83. "The single-step trace trap has been encountered." This corresponds to the
  84. 680x0 trace trap, and is usually activated (and handled) by debuggers;
  85. user programs shouldn't catch this.
  86.  
  87. #define SIGABRT        6
  88. "An awful error has occured." This is commonly sent by the abort library
  89. function, and indicates that something has gone very, very wrong (for
  90. example, data structures have been unexpectedly corrupted). It is unlikely
  91. that anything useful can be done after this signal is sent; programs
  92. should not normally catch or ignore SIGABRT.
  93.  
  94. #define SIGPRIV        7
  95. "Privilege violation." An attempt has been made to execute an instruction
  96. in user mode that is normally restricted to supervisor mode; this corresponds
  97. to the 680x0 privilege violation exception, and indicates a serious error.
  98.  
  99. #define SIGFPE        8
  100. "Division by zero or a floating point error has occured." Processes may
  101. ignore or catch this signal (which corresponds to the 680x0 division by zero
  102. trap) and deal with it as they see fit.
  103.  
  104. #define SIGKILL        9        [cannot be blocked or caught]
  105. "Die!" This signal will never be seen by a process; nor can processes
  106. block it. Sending SIGKILL is a way to be sure of killing a run-away
  107. process. Use it only as a last resort, since it gives the process no
  108. chance to clean up and exit gracefully.
  109.  
  110. #define SIGBUS        10
  111. "Bus error." Corresponds to the 680x0 bus error exception, and indicates
  112. a very serious error; programs should generally not attempt to ignore
  113. or catch this signal.
  114.  
  115. #define SIGSEGV        11
  116. "Illegal memory reference." Corresponds to the 680x0 address error
  117. exception, and indicates a very serious error; catching or ignoring this
  118. signal is not recommended.
  119.  
  120. #define SIGSYS        12
  121. "Bad argument to a system call." This signal is sent when an illegal
  122. (usually, out of range) parameter is sent to a system call, and when that
  123. system call does not have any "nice" way to report errors. For example,
  124. Super(0L) when the system is already in supervisor mode causes SIGSYS to
  125. be raised. Note that the kernel does not always detect illegal/out of
  126. range arguments to system calls, only sometimes.
  127.  
  128. #define SIGPIPE        13
  129. "A pipe you were writing to has no readers." Programs may catch this signal
  130. and attempt to exit gracefully after receiving it; note that exiting is
  131. appropriate because the standard output is probably no longer connected
  132. to anything.
  133.  
  134. #define SIGALRM        14
  135. "The alarm you set earlier has happened." This signal is sent to processes
  136. when the alarm clock set by Talarm (q.v.) expires. It's very
  137. common to catch this signal and from the signal handler jump to a known
  138. point in the program; for example, to indicate a timeout while attempting
  139. to communicate over a serial line.
  140.  
  141. #define SIGTERM        15
  142. "Please die." This is a polite form of SIGKILL (#9). Programs should
  143. respect this nice request; they may want to catch the signal to perform
  144. some cleanup actions, but they should then exit (since if they don't,
  145. the user will probably get mad and send SIGKILL later anyway...). This
  146. is the signal that is sent when a process is dragged to the trashcan on
  147. the desktop.
  148.  
  149. #define SIGSTOP        17        [default action: suspend the process]
  150. "Suspend yourself." This signal is sent to a process when it should be
  151. stopped temporarily. SIGSTOP is used primarily by debuggers and similar
  152. programs; suspensions requested directly by the user usually are signalled
  153. by SIGTSTP (q.v.) This signal cannot be ignored, blocked, or caught.
  154.  
  155. #define SIGTSTP        18        [default action: suspend the process]
  156. "The user is asking you to suspend yourself." This signal is sent immediately
  157. when the user presses the control-Z key, and is sent when the process tries
  158. to read a control-Y key in cooked mode (for a delayed stop). In both cases,
  159. the process should suspend itself. Since this is the default action, no
  160. special handling is normally required, although some programs may wish to
  161. save the screen state and restore it when they are unsuspended.
  162.  
  163. #define SIGCONT        19        [default action: continue a stopped
  164.                      process]
  165. "You are being restarted after having been suspended." This signal is
  166. sent by shells to resume a suspended process. If the process is not
  167. suspended, the signal does nothing. This signal cannot be blocked, but
  168. it *is* possible to install a handler for it (this is rarely necessary,
  169. though).
  170.  
  171. #define SIGCHLD        20        [default action: no action taken]
  172. "One of your children has been suspended or has exited." This signal is
  173. sent by the kernel to the parent of any process that is terminated (either
  174. because of a signal or by a Pterm, Pterm0, or Ptermres system call) or
  175. which is suspended because of a signal. Programs that are concerned with the
  176. status of their children (for example, shells) may wish to catch this signal;
  177. after a SIGCHLD has been received, the Pwait3 system call may be
  178. used to determine exactly which child has exited or been suspended.
  179.  
  180. #define SIGTTIN        21        [default action: suspended the process]
  181. "Attempt to read from a terminal you don't own." This signal is sent to
  182. any process that attempts to do input from a terminal with a different
  183. process group than their own. Usually, this happens if the user has started
  184. the job in the background; the process will be suspended until the user
  185. explicitly brings it to the foreground with the appropriate shell command
  186. (at which time the shell will reset the terminal's process group and
  187. send the stopped process a SIGCONT signal to tell it to continue).
  188. [NOTE: in fact, SIGTTIN and SIGTTOU are sent to all processes in the same
  189. process group as the process that attempted to do the i/o; this is for
  190. compatibility with Unix, and it simplifies the implementation of job
  191. control shells.]
  192.  
  193. #define SIGTTOU        22        [default action: suspend the process]
  194. "Attempt to write to a terminal that you don't own." Similar to SIGTTIN (q.v.).
  195. Processes should normally respect the user's job control and should
  196. override or ignore SIGTTOU only in situations where a very critical error
  197. has occured and a message must be printed immediately.
  198.  
  199. #define SIGXCPU        24
  200. "Your CPU time limit has been exhausted." Sent to processes when they have
  201. consumed more than the maximum number of milliseconds of CPU time allowed
  202. by the Psetlimit() system call. The signal will continue to be sent to
  203. the process until it exits; if a process does catch this signal, it should
  204. do whatever clean up actions are necessary and then terminate.
  205.  
  206. #define SIGWINCH    28        [default action: no action taken]
  207. "The window you were running in has changed size." This signal is sent
  208. to processes by some window managers to indicate that the user has changed
  209. the size of the window the process is running in. If the process cares
  210. about the window size, it may catch this signal and use an Fcntl call
  211. to inquire about the new window size when the signal is received.
  212. (See the documentation for Fcntl for details.)
  213.  
  214. #define SIGUSR1        29
  215. #define SIGUSR2        30
  216.  
  217. These two signals are reserved for applications, which may define whatever
  218. meaning they wish for them. Note, however, that these signals do
  219. terminate processes by default, so don't send them to a process which
  220. isn't prepared to deal with them.
  221.  
  222.  
  223. System Calls Dealing With Signals
  224.  
  225.  
  226. WORD
  227. Pkill( WORD pid, WORD sig )
  228.  
  229. If pid > 0, then the given signal (see the numbers above) is sent to the
  230. process with that pid.
  231. If pid == 0, then the given signal is sent to all members of the process
  232. group of the process making the Pkill call. This includes, of course,
  233. the process itself.
  234. If pid < 0, the signal is sent to all members of process group (-pid).
  235.  
  236. Returns:
  237. 0     for successful sending of the signal
  238.     (Note that if the current process is a recipient of the signal,
  239.     and the signal proves to be fatal, then Pkill will never return.)
  240. ERANGE    if "sig" is less than 0 or greater than 31
  241. EFILNF    if pid > 0 and the indicated process has terminated or does not
  242.     exist, or if pid < 0 and there are no processes in the given
  243.     process group
  244. EACCDN  if the sending process is not authorized to send signals to
  245.     the specified receiving process or group (for example, they
  246.     belong to different users)
  247.  
  248.  
  249. #define SIG_DFL (0L)
  250. #define SIG_IGN (1L)
  251.  
  252. LONG
  253. Psignal(WORD sig, LONG handler)
  254.  
  255. Change the handling of the indicated signal.
  256.  
  257. If "handler" is SIG_DFL, then the default action for the signal will occur when
  258. the signal is delivered to the current process.
  259.  
  260. If "handler" is SIG_IGN, then the signal will be ignored by the process, and
  261. delivery of the signal will have no noticeable effect (in particular, the
  262. signal will not interrupt the Pause system call, q.v.). If the signal
  263. is pending at the time of the Psignal call, it is discarded.
  264.  
  265. If "handler" is any other value, it is assumed to be the address of a
  266. user function that will be called when the signal is delivered to the
  267. process. The user function is called with a single LONG argument on
  268. the stack, which is the number of the signal being delivered (this is done
  269. so that processes may use the same handler for a number of different
  270. signals). While the signal is being handled, it is blocked from delivery;
  271. thus, signal handling is "reliable" (unlike Version 7 and early System V
  272. Unix implementations, in which delivery of a second signal while it
  273. was being handled could kill the process). Also note that, unlike some
  274. versions of Unix, the signal handling is *not* reset to the default action
  275. before the handler is called; it remains set to the given signal handler.
  276.  
  277. The signal handler must either return (via a normal 680x0 rts instruction)
  278. or call the Psigreturn system call to indicate when signal handling is
  279. complete; in both cases, the signal will be unblocked. Psigreturn also
  280. performs some internal clean-up of the kernel stack that is necessary if
  281. the signal handler is not planning to return (for example, if the C
  282. longjmp() function is to be used to continue execution at another point
  283. in the program).
  284.  
  285. Signal handlers may make any GEMDOS, BIOS, or XBIOS system calls freely.
  286. GEM AES and VDI calls should not be made in a signal handler.
  287.  
  288. Note that calling Psignal to change behavior of a signal has the side
  289. effect of unmasking that signal, so that delivery is possible. This is done
  290. so that processes may, while handling a signal, reset the behavior and
  291. send themselves another instance of the signal, for example in order
  292. to suspend themselves while handling a job control signal.
  293.  
  294. Signal handling is preserved across Pfork and Pvfork calls. Signals
  295. that are ignored by the parent are also ignored by the child after a Pexec
  296. call; signals that were being caught for handling in a function are reset
  297. in the child to the default behavior.
  298.  
  299. Returns:
  300. The old value of handler on success.
  301. ERANGE    if sig < 0 or sig > 31
  302. EACCDN    if sig cannot be caught by the user (i.e. SIGKILL or SIGSTOP)
  303.  
  304. Bugs:
  305. Signal handling can be nested only a small (around 3) number of times,
  306. i.e. if 4 signals are delivered to a process, and the process has established
  307. handlers for all 4, and none of the handlers has returned or called
  308. Psigreturn, then there is a very good chance of a stack overflow killing
  309. the process off. In practice, this is unlikely to happen.
  310.  
  311.  
  312. LONG
  313. Psigblock( LONG amask )
  314.  
  315. Block receipt of some signals. The "amask" argument is added to the
  316. current set of signals being masked, i.e. the new set of blocked signals
  317. is the union of the old set and the set represented by amask. Sets of
  318. blocked signals are represented by a 32 bit unsigned long quantity, with
  319. bit (1L << sig) set if signal "sig" is to be blocked, and clear if not.
  320.  
  321. Blocked signals remain blocked across Pfork and Pvfork calls. For Pexec
  322. calls, children always start out with an empty set of blocked signals,
  323. regardless of which signals are blocked in the parent.
  324.  
  325. Returns:
  326. The old set of blocked signals (i.e. the set as it was before amask
  327. was added to it).
  328.  
  329. NOTE: Certain signals (SIGKILL, SIGSTOP, SIGCONT) cannot be blocked;
  330. if the corresponding bits are set in amask, the kernel will clear them
  331. but will not report an error.
  332.  
  333.  
  334. LONG
  335. Psigsetmask( LONG mask )
  336.  
  337. Decide which signals are to be blocked from delivery. Unlike Psigblock
  338. (which adds to the set of blocked signals) Psigsetmask changes the
  339. entire set, replacing the old set of blocked signals with the one
  340. specified in "mask". As with Psigblock, signal n is blocked from
  341. delivery if bit (1L << n) is set in mask. Note that certain signals
  342. cannot be blocked, and if the corresponding bits are set in the
  343. mask the kernel will clear them.
  344.  
  345. Returns:
  346. The old set of blocked signals.
  347.  
  348. Usage:
  349. Typically, Psigblock and Psigsetmask are used together to temporarily
  350. block signals, e.g.:
  351.  
  352.     oldmask = Psigblock( (1L << SIGINT) );
  353.     ... do some things with SIGINT blocked from delivery ...
  354.     (void) Psigsetmask(oldmask);
  355.  
  356.  
  357.  
  358. LONG
  359. Psigpending()
  360.  
  361. Give an indication of what signals are pending (i.e. have been sent to
  362. the process but not yet delivered, probably because they are blocked
  363. from delivery).
  364.  
  365. Returns:
  366. A 32 bit unsigned long representing the set of signals that are pending.
  367. Signal n is pending if bit (1L << n) is set in the returned value.
  368.  
  369.  
  370. void
  371. Psigreturn()
  372.  
  373. Terminate signal handling. This call should be used by any signal
  374. handler that is not planning to return to the kernel (i.e. if the
  375. handler is going to execute a non-local jump to another point in the
  376. program). It cleans up the signal delivery stack and unblocks the
  377. signal that was being delivered. Calling Psigreturn when no signal
  378. is being delivered is harmless.
  379.  
  380. Bugs:
  381. Calling Psigreturn from a signal handler, and then actually returning
  382. from that handler, is likely to produce extremely unpleasant results.
  383. Don't do it.
  384.  
  385.  
  386. void
  387. Pause()
  388.  
  389. Wait until a signal is delivered. This call will return after any (non-fatal)
  390. signal has been delivered to the process. Note that signals that are being
  391. ignored are never delivered.
  392.  
  393.  
  394. LONG
  395. Talarm( LONG s )
  396.  
  397. If s > 0, schedule a SIGALRM signal to occur in s seconds. This alarm
  398. will replace any previously scheduled alarm.
  399. If s = 0, cancel any previously scheduled alarm.
  400. If s < 0, inquire about a scheduled alarm but do not change it.
  401.  
  402. Returns:
  403. If an alarm was previously scheduled, returns the number of seconds remaining
  404. until that previously scheduled alarm. Otherwise, returns 0.
  405.  
  406. Bugs:
  407. Internal calculations are done in milliseconds, not seconds, so the returned
  408. value is not exactly accurate.
  409. For the same reason, setting an alarm more than 2 million seconds or so
  410. into the future will not work correctly.
  411.